package com.ruoyi.cs.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.banbeiPay.Disguiser;
import com.ruoyi.common.banbeiPay.HttpClientService;
import com.ruoyi.common.banbeiPay.MyBeanUtils;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.Response;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.AppCreateOrderResponseVo;
import com.ruoyi.common.utils.bean.AppCreateOrderVo;
import com.ruoyi.common.utils.bean.NotifyResponseVo;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.cs.domain.TRecharge;
import com.ruoyi.cs.domain.TUser;
import com.ruoyi.cs.mapper.TBalanceChangeMapper;
import com.ruoyi.cs.mapper.TRechargeMapper;
import com.ruoyi.cs.mapper.TUserMapper;
import com.ruoyi.cs.mapper.TUserSyMapper;
import com.ruoyi.cs.service.CommonService;
import com.ruoyi.cs.service.IBHLPayService;
import com.ruoyi.system.mapper.SysConfigMapper;
import com.ruoyi.system.mapper.SysDictDataMapper;
import org.apache.commons.httpclient.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;

/**
 * 宝和利支付
 */
@Service
@SuppressWarnings("ALL")
public class BHLPayServiceImpl implements IBHLPayService {

    private static final Logger log = LoggerFactory.getLogger(BHLPayServiceImpl.class);

    @Value("${ruoyi.bhlpayNotify}")
    private String bhlpayNotify;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private TUserMapper userMapper;

    @Autowired
    private CommonService commonService;

    @Autowired
    private SysDictDataMapper sysDictDataMapper;

    @Autowired
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private TRechargeMapper tRechargeMapper;

    @Autowired
    private TUserSyMapper tUserSyMapper;

    @Autowired
    private TBalanceChangeMapper tBalanceChangeMapper;


    @Override
    public Response<Map> bhlRecharge(String userId, BigDecimal czMoney, String czEquipment) throws Exception {
        TUser tUser = userMapper.selectTUserById(userId);
        BigDecimal giveFee = new BigDecimal("0");
        try {
            giveFee = commonService.rechargeVerification(tUser, czMoney);
        } catch (Exception e) {
            return Response.fail(e.getMessage());
        }
        Map<String, Object> resultMap = null;
        try {
            String out_trade_no = DateUtils.dateTimeNow() + IdUtils.fastUUID().substring(0, 8);
            /**宝和利支付单元:元*/
            BigDecimal fee = czMoney.multiply(new BigDecimal(6.5)).setScale(2, BigDecimal.ROUND_HALF_UP);

            AppCreateOrderVo orderVo = this.createOrderParam(out_trade_no, fee.toString(), bhlpayNotify);
            Map<String, String> map = MyBeanUtils.convertBean(orderVo, new LinkedHashMap());
            String oriMessage = MyBeanUtils.getSignedByPresetParameter(map, AppCreateOrderVo.NEED_SIGN_PARAMS, false);
            String sign = Disguiser.disguiseMD5(oriMessage.trim());
            map.put("sign", sign);
            log.info("宝和利支付传参数：" + map);
            resultMap = HttpClientService.getHttpResp(map, Constants.REQUEST_URL);
            log.info("宝和利支付响应结果：" + resultMap);
            if ((Integer) resultMap.get("statusCode") == HttpStatus.SC_OK) {
                /** 需要排除签名的,后续可能会增加*/
                String resultMsg = (String) resultMap.get("response");

                AppCreateOrderResponseVo orderResponseVo = JSONObject.parseObject(resultMsg, AppCreateOrderResponseVo.class);
                String assemblyRespOriSign = MyBeanUtils.getSignedByPresetParameter(orderResponseVo, AppCreateOrderResponseVo.NEED_SIGN_PARAMS, false);
               /**组装返回结果签名串*/
                String responseSign = orderResponseVo.getSign();
                JSONObject jsonObject = JSONObject.parseObject(resultMsg);

                String checkSign = Disguiser.disguiseMD5(assemblyRespOriSign.trim());
                if (checkSign.equals(responseSign)) {
                    if ("0000".equals(orderResponseVo.getRt2_retCode())) {
                        String picurl = null;
                        String rt8_qrcord = orderResponseVo.getRt8_qrcode();
                        try {
                            /**生产二维码图片*/
                            picurl = commonService.scQrCodeImge(rt8_qrcord);
                        } catch (Exception e) {
                            log.error("宝和利支付生产二维码订单异常:{}", e.getMessage());
                            e.printStackTrace();
                            return Response.fail("发送请求失败");
                        }
                        TRecharge tRecharge = new TRecharge();
                        tRecharge.setUserId(userId);
                        tRecharge.setCzId(out_trade_no);
                        tRecharge.setDelFlag(Constants.SUCCESS);
                        tRecharge.setCzType(Constants.ALIPAY);
                        /**支付结果  0 待充值 1充值成功 2充值失败*/
                        tRecharge.setCzStatus(Constants.CZSTATUS0);
                        /**交易类型*/
                        tRecharge.setCzEquipment(czEquipment);
                        tRecharge.setCreateTime(DateUtils.getNowDate());
                        tRecharge.setGiveFee(giveFee);
                        tRecharge.setCzMoney(czMoney);
                        tRecharge.setCzPlatform(Constants.CZPLATFORM3);
                        tRecharge.setUserType(tUser.getUserType());
                        if (StringUtils.isNotEmpty(tUser.getUserPromotersId())) {
                            tRecharge.setUserPromotersId(tUser.getUserPromotersId());
                        }
                        int count = tRechargeMapper.insertTRecharge(tRecharge);
                        if (count > 0) {
                            Map viewmap = new HashMap();
                            viewmap.put("picUrl", picurl);
                            viewmap.put("czId", out_trade_no);
                            viewmap.put("totalFee", czMoney);
                            viewmap.put("url", rt8_qrcord);
                            log.info("宝和利支付二维码：参数信息：{}，支付金额：{},订单号：{}", JSON.toJSONString(tRecharge), fee, out_trade_no);
                            return Response.success(viewmap);
                        } else {
                            log.error("和利支付充值记录表插入失败：参数信息：{}，支付金额：{},订单号：{}", JSON.toJSONString(tRecharge), fee, out_trade_no);
                            return Response.fail("充值窗口异常，请联系管理员处理!");
                        }
                    } else {
                        log.error("创建宝和利支付订单失败:平台订单号:{},返回信息:{}", orderResponseVo.getRt5_orderId(),orderResponseVo.getRt3_retMsg());
                        return Response.fail("支付接口响应失败，请刷新后再试！");
                    }
                } else {
                    log.error("宝和利支付订单接口验签失败,响应结果:{}，验签结果:{}",resultMsg,responseSign);
                    return Response.fail("签名校验失败，请刷新后重试！");
                }
            } else {
                log.error("宝和利支付建订单失败！，返回结果:{}",resultMap);
                return Response.fail("支付创建订单失败，请刷新后重试！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("宝和利支付创建订单异常，异常信息:{},响应结果:{}",e.getMessage(),resultMap);
            return Response.fail("支付接口响应异常，请刷新后重试！");
        }
    }

    /**
     * 异步通知接口
     *
     * @param request
     * @param response
     * @return
     */
    @Override
    public String bhlPayNotify(NotifyResponseVo notifyResponseVo) {
        try {
            String paramStr = notifyResponseVo.toString();
            log.info("宝和利异步回调参数:{}", paramStr);
            String assemblyRespOriSign = MyBeanUtils.getSignedByPresetParameter(
                    notifyResponseVo, NotifyResponseVo.NEED_SIGN_PARAMS, false);
            String responseSign = notifyResponseVo.getSign();
            String checkSign = Disguiser
                    .disguiseMD5(assemblyRespOriSign.trim());
            if (checkSign.equals(responseSign)) {
                log.info("宝和利异步回调验签成功");
                String out_trade_no = notifyResponseVo.getRt2_orderId();
                TRecharge tRecharge = tRechargeMapper.selectTRechargeById(out_trade_no);

                String order_no = notifyResponseVo.getRt3_systemSerial();
                if (tRecharge != null) {
                    /*成功状态*/
                    String rt4_status = notifyResponseVo.getRt4_status();
                    if (Constants.BHL_SUCCESS.equalsIgnoreCase(rt4_status)) {
                        /**宝和利支付单元:元*/
                        BigDecimal fee = tRecharge.getCzMoney().multiply(new BigDecimal(6.5)).setScale(2, BigDecimal.ROUND_HALF_UP);
                        if(fee.compareTo(new BigDecimal(notifyResponseVo.getRt5_orderAmount())) == 0){
                            if (tRecharge.getCzStatus().equals(Constants.CZSTATUS0)) {
                                commonService.czSuccessHandle(tRecharge,out_trade_no,order_no,paramStr);
                            } else {
                                log.info("用户充值操作已完成,无需重复操作。充值ID:{},充值状态:{}",tRecharge.getCzId(),tRecharge.getCzStatus());
                            }
                            return "success";
                        }else{
                            log.error("订单金额和平台返回金额不一致,充值ID:{},充值金额转换为人民币元:{},支付返回金额:{}",tRecharge.getCzId(),fee,notifyResponseVo.getRt5_orderAmount());
                            return "fail";
                        }
                    } else if(Constants.BHL_FAIL.equalsIgnoreCase(rt4_status) || Constants.BHL_CLOSE.equalsIgnoreCase(rt4_status) || Constants.BHL_CANCEL.equalsIgnoreCase(rt4_status)){
                        if (tRecharge.getCzStatus().equals(Constants.CZSTATUS0)) {
                            commonService.czFailHandle(tRecharge,out_trade_no,order_no,paramStr);
                        }
                        return "success";
                    }
                } else {
                    log.error("查询充值订单信息为空,请求参数：{}",notifyResponseVo.toString());
                    return "fail";
                }
            }else{
                log.info("宝和利异步回调验签失败:签名:{},验签：{}",responseSign,checkSign);
                return "fail";
            }
            return "success";
        } catch (Exception e) {
            log.error("宝和利回调异常信息:{},参数:{}",e.getMessage(),notifyResponseVo.toString());
            e.printStackTrace();
            return "fail";
        }
    }

    /**组装支付参数*/
    private AppCreateOrderVo createOrderParam(String orderid, String czMoney, String chpayNotify) {
        AppCreateOrderVo orderVo = new AppCreateOrderVo();
        orderVo.setP1_bizType("AppPay");
        orderVo.setP2_orderId(orderid);
        orderVo.setP3_customerNumber(Constants.PA_MERCHANT_NO);
        orderVo.setP4_payType("SCAN");
        orderVo.setP5_orderAmount(czMoney);
        orderVo.setP6_currency("CNY");
        orderVo.setP7_authcode("1");
        orderVo.setP8_appType("ALIPAY");
        orderVo.setP9_notifyUrl(chpayNotify);
//        orderVo.setP10_successToUrl("https://wap.bangbeipay.com/success.php");
        orderVo.setP11_orderIp("127.0.0.1");
        orderVo.setP12_goodsName("1818skins");
        /**设置超时时间。订单过期*/
        orderVo.setTimeExpire("20m");
        return orderVo;
    }

}
